#include <NewLife.h>
#include <NewLifeDDK.h>
#include <RequestPackage.h>
#include <stdlib.h>
#include "Driver.h"
#include "IOQueue.h"

void PrintHex(int dat)
{
	static char asc[] = "0123456789ABCDEF";
	__asm__ __volatile__("int $0x90"::"a"('0'));
	__asm__ __volatile__("int $0x90"::"a"('x'));
	for(int i=7; i>=0; i--)
	{
		char c = asc[(dat>>i*4)&0xF];
		__asm__ __volatile__("int $0x90"::"a"(c));
	}
	__asm__ __volatile__("int $0x90"::"a"(' '));
}

int main(void)
{
	CDriver *drv = CDriver::GetInstance();
	CIOQueue *IOQueue = new CIOQueue();
	struct message *msg;
	RequestPackage *IRP;

	// Allocate space for message
	msg = (struct message *)malloc(sizeof(message)+sizeof(RequestPackage));
	msg->size = sizeof(message)+sizeof(RequestPackage);

	// Initialize driver
	drv->InitializeDriver();

	while(1)
	{
		int ret;

		/* Receive a message */
 		receive(PID_ANY, msg);
		IRP = (RequestPackage *)(&msg->dat);

		/* Driver shutdown */
		if(IRP->GetRequestType()==IRP_SHUTDOWN)
		{
			drv->Shutdown();
			break;
		}

		/* System IRQ */	
		if(IRP->GetRequestType()==IRP_IRQ)
		{
			// Handle this IRQ notify
			drv->irq_handler(IRP->GetIRQ());
			IRP->FinishRequest(0);

			// Check if have not pending IRP
			if(IOQueue->GetRequest(&IRP))
			{
				// If can finish this IRP, finish it
				if(drv->ProcessMessage(IRP, &ret))
				{
					IRP->FinishRequest(ret);
					IOQueue->RemoveRequest();
				}
			}
		}

		/* Normal IRP */
		else
		{
			// Can handle this request
			if(drv->ProcessMessage(IRP, &ret))
			{
				IRP->FinishRequest(ret);
			}
			// Can't not handle this request
			else
			{
				IOQueue->AddRequest(IRP);
			}
		}
	}

	return 0;
}

